package com.codefish.framework.spring.aop.framework.adapter;

import com.codefish.framework.spring.aop.IAfterAdvice;
import com.codefish.framework.spring.aop.IAfterThrowingAdvice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 实现方法抛出异常拦截调用
 *
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/10/21 下午 03:46
 */
public class AfterThrowingInterceptor implements MethodInterceptor, IAfterAdvice {

    private final Map<Class<? extends Throwable>, IAfterThrowingAdvice> exceptionHandlingMap = new ConcurrentHashMap<>(8);


    public AfterThrowingInterceptor addExceptionHandler(Class<? extends Throwable> throwableClass, IAfterThrowingAdvice afterThrowingAdvice) {
        this.exceptionHandlingMap.put(throwableClass, afterThrowingAdvice);
        return this;
    }

    public IAfterThrowingAdvice getExceptionHandler(Class<? extends Throwable> throwableClass) {
        return this.exceptionHandlingMap.get(throwableClass);
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
            return invocation.proceed();
        } catch (Throwable throwable) {
            //从handlerMap中找到处理这个异常的handler
            IAfterThrowingAdvice handler = getExceptionHandler(throwable.getClass());
            if (handler != null) {
                //捕获异常，执行回调
                handler.afterThrow(throwable, invocation.getMethod(), invocation.getArguments(), invocation.getThis());
            }
            throw throwable;
        }
    }
}
